home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / utils / xad / developer / sources / clients / tar.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  8KB  |  278 lines

  1. #ifndef XADMASTER_TAR_C
  2. #define XADMASTER_TAR_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        Tar.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: Tar.c 1.0 (07.09.1998)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    Tar file archiver client
  12.  
  13.  1.0   07.09.98 : first version
  14. */
  15.  
  16. #include <proto/xadmaster.h>
  17. #include <proto/exec.h>
  18. #include <dos/dos.h>
  19. #include "SDI_compiler.h"
  20. #define SDI_TO_ANSI
  21. #include "SDI_ASM_STD_protos.h"
  22.  
  23. #ifndef XADMASTERFILE
  24. #define Tar_Client        FirstClient
  25. #define NEXTCLIENT        0
  26. UBYTE version[] = "$VER: Tar 1.0 (07.09.1998)";
  27. #endif
  28. #define TAR_VERSION        1
  29. #define TAR_REVISION        0
  30.  
  31. struct TarHeader
  32. {                /* byte offset */
  33.   UBYTE th_Name[100];        /*   0 */
  34.   UBYTE th_Mode[8];        /* 100 */
  35.   UBYTE th_UserID[8];        /* 108 */
  36.   UBYTE th_GroupID[8];        /* 116 */
  37.   UBYTE th_Size[12];        /* 124 */
  38.   UBYTE th_MTime[12];        /* 136 */
  39.   UBYTE th_Checksum[8];     /* 148 */
  40.   UBYTE th_Typeflag;        /* 156 */
  41.   UBYTE th_LinkName[100];    /* 157 */
  42.   UBYTE th_Magic[6];        /* 257 */
  43.   UBYTE th_Version[2];        /* 263 */
  44.   UBYTE th_UserName[32];    /* 265 */
  45.   UBYTE th_GroupName[32];    /* 297 */
  46.   UBYTE th_DevMajor[8];     /* 329 */
  47.   UBYTE th_DevMinor[8];     /* 337 */
  48.   UBYTE th_Prefix[155];     /* 345 */
  49.   UBYTE th_Pad[12];        /* 500 */
  50. };
  51.  
  52. /* Values used in Typeflag field.  */
  53. #define TF_FILE     '0'  /* Regular file */
  54. #define TF_AFILE    '\0' /* Regular file */
  55. #define TF_LINK     '1'  /* Link */
  56. #define TF_SYM        '2'  /* Reserved - but GNU tar uses this for links... */
  57. #define TF_CHAR     '3'  /* Character special */
  58. #define TF_BLOCK    '4'  /* Block special */
  59. #define TF_DIR        '5'  /* Drawer */
  60. #define TF_FIFO     '6'  /* FIFO special */
  61. #define TF_CONT     '7'  /* Reserved */
  62.  
  63. /* Bits used in the mode field, values in octal.  */
  64. #define TM_SUID       04000 /* Set UID on execution */
  65. #define TM_SGID       02000 /* Set GID on execution */
  66. #define TM_SVTX       01000 /* Reserved */
  67.     /* File permissions */
  68. #define TM_UREAD      00400 /* Read by owner */
  69. #define TM_UWRITE     00200 /* Write by owner */
  70. #define TM_UEXEC      00100 /* Execute/search by owner */
  71. #define TM_GREAD      00040 /* Read by group */
  72. #define TM_GWRITE     00020 /* Write by group */
  73. #define TM_GEXEC      00010 /* Execute/search by group */
  74. #define TM_OREAD      00004 /* Read by other */
  75. #define TM_OWRITE     00002 /* Write by other */
  76. #define TM_OEXEC     00001 /* Execute/search by other */
  77.  
  78. static ULONG octtonum(STRPTR oct, LONG width, LONG *ok)
  79. {
  80.   ULONG i = 0;
  81.  
  82.   while(width-- && *oct == ' ')
  83.     ++oct;
  84.  
  85.   if(!*oct)
  86.     *ok = 0;
  87.   else
  88.   {
  89.     while(width-- && *oct >= '0' && *oct <= '7')
  90.      i = (i*8)+*(oct++)-'0';
  91.  
  92.     if(width > 0 && *oct)    /* an error, set error flag */
  93.       *ok = 0;
  94.   }
  95.  
  96.   return i;
  97. }
  98.  
  99. BOOL checktarsum(struct TarHeader *th)
  100. {
  101.   LONG sc, i;
  102.   ULONG uc, checks;
  103.   
  104.   i = 1;
  105.   checks = octtonum(th->th_Checksum, 8, &i);
  106.   if(!i)
  107.     return DOSFALSE;
  108.  
  109.   for(i = sc = uc = 0; i < 512; ++i)
  110.   {
  111.     sc += ((BYTE *) th)[i];
  112.     uc += ((UBYTE *) th)[i];
  113.   }
  114.   
  115.   for(i = 148; i < 156; ++i)
  116.   {
  117.     sc -= ((BYTE *) th)[i];
  118.     uc -= ((UBYTE *) th)[i];
  119.   }
  120.   sc += 8 * ' ';
  121.   uc += 8 * ' ';
  122.   
  123.   if(checks != uc && checks != (ULONG) sc)
  124.     return DOSFALSE;
  125.   return DOSTRUE;
  126. }
  127.  
  128. ASM(BOOL) Tar_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  129. REG(a6, struct xadMasterBase *xadMasterBase))
  130. {
  131.   if(data[0] > 0x1F && checktarsum((struct TarHeader *) data))
  132.     return 1;
  133.   else
  134.     return 0;
  135. }
  136.  
  137. ASM(LONG) Tar_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  138. REG(a6, struct xadMasterBase *xadMasterBase))
  139. {
  140.   struct TarHeader th;
  141.   struct xadFileInfo *fi = 0, *fi2;
  142.   LONG err, size, ok, a, b, d, i, pos, num = 1;
  143.   struct ExecBase * SysBase = xadMasterBase->xmb_SysBase;
  144.  
  145.   while(!(err = xadHookAccess(XADAC_READ, sizeof(struct TarHeader), &th, ai)))
  146.   {
  147.     if(!th.th_Name[0])
  148.       break;
  149.     ok = checktarsum(&th); /* check checksum and init ok */
  150.     size = octtonum(th.th_Size, 12, &ok);
  151.  
  152.     pos = ai->xai_InPos;
  153.     if(ok && (th.th_Typeflag == TF_FILE || 
  154.     th.th_Typeflag == TF_AFILE) &&
  155.     err != xadHookAccess(XADAC_INPUTSEEK, (size+511)&~511, 0, ai))
  156.       ok = 0;
  157.     if(ok && (th.th_Typeflag == TF_FILE || th.th_Typeflag == TF_AFILE ||
  158.     th.th_Typeflag == TF_DIR || th.th_Typeflag == TF_SYM ||
  159.     th.th_Typeflag == TF_LINK))
  160.     {
  161.       a = strlen(th.th_Name) + 1;
  162.       if(th.th_Name[a-2] == '/')
  163.       {
  164.     if(th.th_Typeflag == TF_AFILE || th.th_Typeflag == TF_FILE)
  165.     {
  166.       th.th_Name[--a-1] == 0;
  167.           th.th_Typeflag = TF_DIR;
  168.         }
  169.       }
  170.       
  171.       b = th.th_LinkName[0] ? 1 + strlen(th.th_LinkName) : 0;
  172.       i = th.th_UserName[0] ? 1 + strlen(th.th_UserName) : 0;
  173.       d = th.th_GroupName[0] ? 1 + strlen(th.th_GroupName) : 0;
  174.       
  175.       if(!(fi2 = (struct xadFileInfo *) xadAllocObject(XADOBJ_FILEINFO,
  176.       XAD_OBJNAMESIZE, a+b+i+d, TAG_DONE)))
  177.       {
  178.         err = XADERR_NOMEMORY; break;
  179.       }
  180.       else
  181.       {
  182.         fi2->xfi_PrivateInfo = (APTR) pos;
  183.     if(th.th_Typeflag == TF_LINK || th.th_Typeflag == TF_SYM)
  184.       fi2->xfi_Flags |= XADFIF_LINK;
  185.     else if(th.th_Typeflag == TF_DIR)
  186.     {
  187.       fi2->xfi_Flags |= XADFIF_DIRECTORY;
  188.       size = 0;
  189.     }
  190.         fi2->xfi_CrunchSize = fi2->xfi_Size = size;
  191.         CopyMem(th.th_Name, fi2->xfi_FileName, a-1);
  192.         if(b)
  193.         {
  194.           fi2->xfi_LinkName = fi2->xfi_FileName + a;
  195.           CopyMem(th.th_LinkName, fi2->xfi_LinkName, b-1);
  196.         }
  197.         if(i)
  198.         {
  199.           fi2->xfi_UserName = fi2->xfi_FileName + a + b;
  200.           CopyMem(th.th_UserName, fi2->xfi_UserName, i-1);
  201.         }
  202.         if(d)
  203.         {
  204.           fi2->xfi_GroupName = fi2->xfi_FileName + a + b + i;
  205.           CopyMem(th.th_GroupName, fi2->xfi_GroupName, d-1);
  206.         }
  207.         fi2->xfi_OwnerUID = octtonum(th.th_UserID, 8, &ok);
  208.         fi2->xfi_OwnerGID = octtonum(th.th_GroupID, 8, &ok);
  209.  
  210.     i = octtonum(th.th_Mode, 8, &ok);
  211.     if(!(i & TM_UREAD))    fi2->xfi_Protection |= FIBF_READ;
  212.     if(!(i & TM_UWRITE))    fi2->xfi_Protection |= FIBF_WRITE;
  213.     if(!(i & TM_UEXEC))    fi2->xfi_Protection |= FIBF_EXECUTE;
  214.     if(i & TM_GREAD)    fi2->xfi_Protection |= FIBF_GRP_READ;
  215.     if(i & TM_GWRITE)    fi2->xfi_Protection |= FIBF_GRP_WRITE;
  216.     if(i & TM_GEXEC)    fi2->xfi_Protection |= FIBF_GRP_EXECUTE;
  217.     if(i & TM_OREAD)    fi2->xfi_Protection |= FIBF_OTR_READ;
  218.     if(i & TM_OWRITE)    fi2->xfi_Protection |= FIBF_OTR_WRITE;
  219.     if(i & TM_OEXEC)    fi2->xfi_Protection |= FIBF_OTR_EXECUTE;
  220.  
  221.         err = xadConvertDates(XAD_DATEUNIX, octtonum(th.th_MTime, 12, &ok),
  222.         XAD_MAKELOCALDATE, 1, XAD_GETDATEXADDATE, &fi2->xfi_Date, TAG_DONE);
  223.  
  224.     if(ok && !err)
  225.     {
  226.       fi2->xfi_EntryNumber = num++;
  227.           if(fi)
  228.             fi->xfi_Next = fi2;
  229.           else
  230.             ai->xai_FileInfo = fi2;
  231.           fi = fi2;
  232.         }
  233.         else
  234.           xadFreeObjectA(fi2, 0);
  235.       }
  236.     }
  237.     if(!ok)
  238.       ai->xai_Flags |= XADAIF_FILECORRUPT;
  239.   }
  240.  
  241.   return err;
  242. }
  243.  
  244. ASM(LONG) Tar_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  245. REG(a6, struct xadMasterBase *xadMasterBase))
  246. {
  247.   LONG i;
  248.  
  249.   if((i = ((LONG) (ai->xai_CurFile->xfi_PrivateInfo)) - ai->xai_InPos))
  250.     if((i = xadHookAccess(XADAC_INPUTSEEK, i, 0, ai)))
  251.       return i;
  252.  
  253.   return xadHookAccess(XADAC_COPY, ai->xai_CurFile->xfi_Size, 0, ai);
  254. }
  255.  
  256. ASM(void) Tar_Free(REG(a0, struct xadArchiveInfo *ai),
  257. REG(a6, struct xadMasterBase *xadMasterBase))
  258. {
  259.   struct xadFileInfo *fi, *fi2;
  260.  
  261.   fi = ai->xai_FileInfo;
  262.   while(fi)
  263.   {
  264.     fi2 = fi->xfi_Next;
  265.     xadFreeObjectA(fi, 0);
  266.     fi = fi2;
  267.   }
  268.   ai->xai_FileInfo = 0;
  269. }
  270.  
  271. struct xadClient Tar_Client = {
  272. NEXTCLIENT, XADCLIENT_VERSION, 1, TAR_VERSION, TAR_REVISION,
  273. 512, XADCF_FILEARCHIVER, XADCID_TAR, "Tar",
  274. (BOOL (*)()) Tar_RecogData, (LONG (*)()) Tar_GetInfo,
  275. (LONG (*)()) Tar_UnArchive, (void (*)()) Tar_Free};
  276.  
  277. #endif /* XADASTER_TAR_C */
  278.